import Axios from 'axios'
import { Message } from 'ant-design-vue'

const baseURL = 'https://api.github.com'

const axios = Axios.create({
  baseURL,
  timeout: 20000 // 请求超时 20s
})

// 前置拦截器（发起请求之前的拦截）
axios.interceptors.request.use(
  config => {
    /**
     * 根据你的项目实际情况来对 config 做处理
     * 这里对 config 不做任何处理，直接返回
     */
    removePendingRequest(config)
    addPendingRequest(config)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 后置拦截器（获取到响应时的拦截）
axios.interceptors.response.use(
  response => {
    /**
     * 根据你的项目实际情况来对 response 和 error 做处理
     * 这里对 response 和 error 不做任何处理，直接返回
     */
    removePendingRequest(response.config)
    return response
  },
  error => {
    removePendingRequest(error.config || {}) // 从pendingRequest对象中移除请求
    if (error.response && error.response.data) {
      const code = error.response.status
      const msg = error.response.data.message
      Message.error(`Code: ${code}, Message: ${msg}`)
      console.error(`[Axios Error]`, error.response)
    } else {
      Message.error(`${error}`)
    }
    return Promise.reject(error)
  }
)

// 创建请求唯一标识
function generateReqKey(config) {
  const { method, url, params, data } = config
  console.log([method, url, qs.stringify(params), qs.stringify(data)].join('&'))
  return [method, url, qs.stringify(params), qs.stringify(data)].join('&')
}
const pendingRequest = new Map() // 存储请求唯一标识key

// 根据请求标识创建对用的cancelToken函数
function addPendingRequest(config) {
  const requestKey = generateReqKey(config)
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken(cancel => {
      if (!pendingRequest.has(requestKey)) {
        pendingRequest.set(requestKey, cancel)
      }
    })
}
// export let axiosCancel
// 根据请求标识移除对应的cancelToken函数，取消请求
export function removePendingRequest(config) {
  const requestKey = generateReqKey(config)
  if (pendingRequest.has(requestKey)) {
    const axiosCancel = pendingRequest.get(requestKey)
    axiosCancel('取消请求')
    pendingRequest.delete(requestKey)
  }
}

export default axios
